package com.hyt.it.ogt.kq.common.bm.utils;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.hyt.it.ogt.kq.common.utils.KqStringUtils;

public class QRCodeUtil {
	private static final int QRCOLOR = 0xFF000000; // 二维码颜色 默认是黑色
	private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色
	private static final int WIDTH = 375; // 二维码宽
	private static final int HEIGHT = 375; // 二维码高
	private static final int WORDHEIGHT = 415; // 加文字二维码高

	public static void createZxing(String path, String content,
			int qrCodeSize, String imageFormat) throws Exception {
		Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 纠错等级L,M,Q,H
		hints.put(EncodeHintType.MARGIN, 2); // 边距
		// 创建比特矩阵(位矩阵)的QR码编码的字符串
		BitMatrix bitMatrix = new MultiFormatWriter().
				encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize,
				hints);
		File file = new File(path);
		// 使用比特矩阵画并保存图像
		MatrixToImageWriter.writeToFile(bitMatrix, imageFormat, file);
	}

	/**
	 * 用于设置QR二维码参数
	 */
	private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>() {
		private static final long serialVersionUID = 1L;
		{
			// 设置QR二维码的纠错级别（H为最高级别）具体级别信息
			put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
			// 设置编码方式
			put(EncodeHintType.CHARACTER_SET, "GBK");
			put(EncodeHintType.MARGIN, 0);
		}
	};

	/**
	 * 设置 Graphics2D 属性 （抗锯齿）
	 *
	 * @param graphics2D 
	 */
	private static void setGraphics2D(Graphics2D graphics2D) {
		graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
		Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
		graphics2D.setStroke(s);
	}

	/**
	 * 生成二维码图片存储到filePath中
	 *
	 * @param content  二维码内容
	 * @param filePath 成二维码图片保存路径
	 * @return boolean 
	 */
	public static boolean createImg(String content, String filePath) {
		boolean flag = false;
		try {
			MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
			BitMatrix bitMatrix = multiFormatWriter
					.encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);

			// 图片输出路径
			String code = content.split("=")[1]; // 设备编号

			File file = new File(filePath + "//PSD" + code + ".jpg");
			if (!file.exists()) {
				// 如果文件夹不存在则创建
				file.mkdirs();
			}

			// 输出二维码图片到文件夹
			MatrixToImageWriter.writeToFile(bitMatrix, "jpg", file);
			flag = true;

		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 把带logo的二维码下面加上文字
	 *
	 * @param image 
	 * @param words 
	 * @return BufferedImage 
	 */
	private static BufferedImage insertWords(BufferedImage image, String words) {
		// 新的图片，把带logo的二维码下面加上文字
		if (KqStringUtils.isNotBlank(words)) {

			// 创建一个带透明色的BufferedImage对象
			BufferedImage outImage = new BufferedImage(WIDTH, WORDHEIGHT, BufferedImage.TYPE_INT_ARGB);
			Graphics2D outg = outImage.createGraphics();
			setGraphics2D(outg);

			// 画二维码到新的面板
			outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
			// 画文字到新的面板
			Color color = new Color(0, 0, 0);
			outg.setColor(color);
			outg.setFont(new Font("粗体", Font.BOLD, 25));
			// 字体、字型、字号
//			outg.setFont(new Font("微软雅黑", Font.PLAIN, 35));
			// 文字长度
			int strWidth = outg.getFontMetrics().stringWidth(words);
			// 总长度减去文字长度的一半 （居中显示）
			int wordStartX = (WIDTH - strWidth) / 2;
			// height + (outImage.getHeight() - height) / 2 + 12
			int wordStartY = HEIGHT + 35;
			// 画文字
			outg.drawString(words, wordStartX, wordStartY);
			outg.dispose();
			outImage.flush();
			return outImage;
		}
		return null;
	}

	/**
	 * @param qrUrl  二维码内容
	 * @param words  二维码下面的文字
	 * @return byte 
	 * @exception Exception 
	 */
	public static byte[] drawLogoQRCode(String qrUrl, String words) throws Exception {
		MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
		// 参数顺序分别为：编码内容，编码类型，生成图片宽度，生成图片高度，设置参数
		BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
		BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

		// 开始利用二维码数据创建Bitmap图片，分别设为黑（0xFFFFFFFF）白（0xFF000000）两色
		for (int x = 0; x < WIDTH; x++) {
			for (int y = 0; y < HEIGHT; y++) {
				image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
			}
		}

		// 新的图片，把带logo的二维码下面加上文字
//		image = insertWords(image, words);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		image.flush();
		ImageIO.write(image, "png", out);
		byte[] bytes = out.toByteArray();
		return bytes;

	}

	public static void main(String[] args) throws Exception {

		// 生成图片
		File qrCodeFile = new File("D://test1.png");
		// 二维码内容
		String url = "https://ks.shmftpp.com/ogt/f?officeCode=PAZN001";
		// 二维码下面的文字
		String words = "PSD000001";
		String path = "D://";
		byte[] bytes = drawLogoQRCode(url, words);
		getFileByBytes(bytes, path, "test1.png");
	}

	public static void getFileByBytes(byte[] bytes, String filePath, String fileName) {
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			File dir = new File(filePath);
			if (!dir.exists() && dir.isDirectory()) {// 判断文件目录是否存在
				dir.mkdirs();
			}
			file = new File(filePath + "\\" + fileName);
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bytes);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static String getPath(String projectId, String basePath) {

		String path = projectId + ".png";
		File file = new File(basePath + path);
		if (file.exists()) {
			return basePath + path;
		}
		return "";
	}
}
